<template>
  <div>
    <slot></slot>
  </div>
</template>

<script>
export default {
  name: "ChartJsGenerate",
  data() {
    return {
      instances: {},
      chartDom: null,
      // 默认柱子宽度
      barHeight: 40,
      // 调整步幅
      step: 90,
    };
  },
  created() {},
  mounted() {
    var _this = this;
    // 自动生成图表
    if (_this.enableAuto) {
      _this.generateChartById(
        _this.chartId,
        _this.chartData,
        _this.otherOption,
        _this.ratio
      );
    }
  },
  components: {},
  props: {
    ratio: {
      type: Number,
    },
    // 坐标对应的 传入数据指定的键值
    nameDataKey: {
      type: String,
      default: "name",
    },
    // 数据对应的 传入数据指定的键值
    valueDataKey: {
      type: String,
      default: "value",
    },
    customOption: {
      type: Object,
      default: function () {
        return {};
      },
    },
    cultureMap: {
      type: Map,
      default: function () {
        return new Map();
      },
    },
    // 图表数据
    chartData: {
      type: Array,
      default: function () {
        return [];
      },
    },
    // 其他设置
    otherOption: {
      type: Object,
      default: function () {
        return {};
      },
    },
    // 图表id
    chartId: {
      type: String,
      default: null,
    },
    // 自动生成开关
    enableAuto: {
      type: Boolean,
      default: false,
    },
  },
  methods: {
    // 获取宽度
    getWidth: function () {
      xWidth = null;
      if (window.screen != null) xWidth = window.screen.availWidth;

      if (window.innerWidth != null) xWidth = window.innerWidth;

      if (document.body != null) xWidth = document.body.clientWidth;

      return xWidth;
    },

    // 动态获取比例
    getRatio: function (id, total, barHeight, step) {
      var _this = this;
      // 图标宽度 默认是屏幕宽度
      var chartWidth = _this.getWidth();
      // 如果能获取到父元素
      let element = document.getElementById(id);
      if (element) {
        let parent = element.parentElement;
        if (parent) {
          chartWidth = parent.clientWidth;
        }
        return parseFloat(
          chartWidth / ((barHeight + (1 / total) * step) * total)
        ).toFixed(2);
      } else {
        return null;
      }
    },

    // 根据chartId 生成图表 (部分特殊处理)
    generateChartById(id, list, otherOption, ratio) {
      var _this = this;
      var preId = id;
      var suffixId = "";
      if (id.includes("_")) {
        preId = id.split("_")[0];
        suffixId = id.split("_")[1];
      }
      switch (preId) {
        case "chart-life-index":
          _this.generateChart(
            id,
            "bar",
            "LifeIndex",
            1.2,
            "withoutToolTipIndex",
            list
          );
          break;
        case "chart-norm-1-compare":
          _this.generateChart(
            id,
            "bar",
            "PQ24NormDataLand",
            4.6,
            "withToolTipPercentLand",
            list
          );
          break;
      }
    },

    // 图表数据
    chartDataFactory(chartType, chartInData) {
      let _this = this;
      let chartOutData = {};
      switch (chartType) {
        // 根据需求配置数据
        case "LifeIndex":
          chartOutData = {
            labels: chartInData.title,
            datasets: [
              {
                data: chartInData.score,
                tooltipText: chartInData.desc,
                backgroundColor: chartInData.color,
                datalabels: {
                  color: "black",
                  anchor: "end",
                  align: "left",
                  offset: 6,
                },
              },
            ],
          };
          break;
      }

      return chartOutData;
    },
    // 配置option
    setOption(ratio, optionType, otherOption) {
      let _this = this;
      let option = {};

      switch (optionType) {
        case "withoutToolTipIndex":
          option = {
            indexAxis: "y",
            scales: {
              x: {
                suggestedMin: 0,
                suggestedMax: 100,
              },
              yAxes: [
                {
                  ticks: {
                    fontSize: 30,
                  },
                },
              ],
            },
            aspectRatio: ratio,
            plugins: {
              legend: false,
            },
          };
          break;
      }

      return option;
    },
    // 设置配置
    setConfig(type, data, options) {
      let chartConfig = {
        type: type,
        data: data,
        plugins: [],
        options: options,
      };
      return chartConfig;
    },
    // 生成图表需要的数据
    // list - 对象数组
    // sortProp - 要排序的属性值
    // limit - 限制取多少个 （默认先排序后取) from - 开始下标 to - 结束下标
    // otherOption - 额外要配置的属性 要求对象
    generateChartInData(list, sortProp, limit, otherOption) {
      if (sortProp) {
        list = sortByProperty(list, sortProp);
      }
      if (limit) {
        list = list.slice(limit.from, limit.to);
      }
      let chartInData = {};
      // 保证list中的每个对象的属性名是相同的，也就是说一一对应
      for (let attr1 in list[0]) {
        // 以每个属性名为名字构建数组
        chartInData[attr1] = [];
      }
      list.forEach((item, index) => {
        for (let attr2 in item) {
          // chartInData[attr2] 为underfined时 初始化为空数组
          if (!chartInData[attr2]) {
            chartInData[attr2] = [];
          }
          chartInData[attr2].push(item[attr2]);
        }
      });

      // option有值 则将option上的属性添加到生成的对象
      if (otherOption) {
        for (let attr3 in otherOption) {
          chartInData[attr3] = otherOption[attr3];
        }
      }
      return chartInData;
    },

    // 生成图表
    // id 图标id
    // type 配置类型
    // chartType 图标类型
    // ratio tooltip的aspectRatio
    // optionType option类型
    // list 要生成图表的数据列表
    // sortProp 要排序的字段
    // limit 是对象 字段有from和to 表示
    // otherOption - 额外要配置的属性 要求对象
    generateChart(
      id,
      type,
      chartType,
      ratio,
      optionType,
      list,
      sortProp,
      limit,
      otherOption
    ) {
      let _this = this;
      let chartInData = _this.generateChartInData(
        list,
        sortProp,
        limit,
        otherOption
      );
      if (document.getElementById(id)) {
        let chart = _this.getChart(id);
        // 存在表格的话先进行销毁
        if (chart !== undefined) {
          chart.destroy();
        }
        let data = _this.chartDataFactory(chartType, chartInData);
        new Chart(
          document.getElementById(id),
          _this.setConfig(type, data, _this.setOption(ratio, optionType))
        );
      }
    },

    // 生成有多条数据的图标
    // list是包含多条数据的数组
    generateChartWithMultiData: function (
      id,
      type,
      chartType,
      ratio,
      optionType,
      list,
      sortProp,
      limit,
      otherOption
    ) {
      var _this = this;
      var chartInData = null;
      var chartDom = document.getElementById(id);
      if (chartDom) {
        var chart = Chart.getChart(id);
        // 存在表格的话先进行销毁
        if (chart !== undefined) {
          chart.destroy();
        }
        if (Array.isArray(list) && list.length > 0) {
          chartDom.style.display = "block";
          // list是包含多条数据的数组
          chartInData = list.map(function (item) {
            // item 是24dna列表
            return _this.generateChartInData(
              item,
              sortProp,
              limit,
              otherOption
            );
          });
        } else {
          chartDom.style.display = "none";
          return;
        }
        var data = _this.chartDataFactory(chartType, chartInData, chartDom);
        Chart.defaults.color = "#000";
        new Chart(
          document.getElementById(id),
          _this.setConfig(
            type,
            data,
            _this.setOption(ratio, optionType, otherOption)
          )
        );
      }
    },

    isDomSupported() {
      return typeof window !== "undefined" && typeof document !== "undefined";
    },
    getCanvas(item) {
      if (this.isDomSupported() && typeof item === "string") {
        item = document.getElementById(item);
      } else if (item && item.length) {
        item = item[0];
      }
      if (item && item.canvas) {
        item = item.canvas;
      }
      return item;
    },
    // 根据id获取图表
    getChart(key) {
      const canvas = this.getCanvas(key);
      return Object.values(this.instances)
        .filter((c) => c.canvas === canvas)
        .pop();
    },

    // 数组根据某个指定的属性排序
    sortByProperty: function (list, property) {
      list = list.sort(function (value1, value2) {
        var a = value1[property];
        var b = value2[property];
        return a < b ? 1 : a > b ? -1 : 0;
      });
      return list;
    },
  },
};
</script>

<style>
</style>